package com.teamsun.mqtt.service;

import io.netty.handler.codec.mqtt.MqttQoS;

import java.util.Calendar;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.DelayQueue;

import com.teamsun.mqtt.entity.MsgRep;
import com.teamsun.mqtt.entity.vo.DelaySnedMsg;
/**
 * 重发机制服务
 * @author acer
 *
 */
public class ReSendService {

	DelayQueue<DelaySnedMsg> delayQueue=new DelayQueue<DelaySnedMsg>();
	
	ConcurrentMap<String, DelaySnedMsg> concurrentMap=new ConcurrentHashMap<String, DelaySnedMsg>();
	
	static ReSendService reSendService;
	
	private ReSendService(){
	   start();
	}
	/**
	 * 单例模式
	 * @return
	 */
	public  static ReSendService getIntanceo(){
		
		if(reSendService==null)
			reSendService=new ReSendService();
		
		return  reSendService;
	}
	
	 
	 
	public  void submit(DelaySnedMsg delaySnedMsg){
		delayQueue.offer(delaySnedMsg);
		
		MsgRep msgRep=delaySnedMsg.getTransportMessage();
		concurrentMap.put(
				delaySnedMsg.getClientid()+msgRep.getMessageid(),
				delaySnedMsg);
	}
	/**
	 * 启动一个线程重新发送消息给客户端
	 */
	public   void  start(){
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				
				
				while(true){
					DelaySnedMsg delaySnedMsg=null;
					 try {
					System.out.println( delaySnedMsg=delayQueue.take());
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					 
					 if(delaySnedMsg!=null){
						 
						 MessageDataService.sendMsg2Client(delaySnedMsg.getTransportMessage(), 
								 delaySnedMsg.getClientid(),MqttQoS.EXACTLY_ONCE);
					 }
				}
				
			}
		}, "checksuccess").start();
	}
	
	/**
	 * 按照接受客户端标识和消息id把这个代发消息移除队列
	 * @param clientid
	 * @param msgid
	 * @return
	 */
	public  boolean  removeReSend(String clientid,Integer msgid){
		
		String key=clientid+msgid;
		if(concurrentMap.containsKey(key)){
			 if(delayQueue.remove(concurrentMap.get(key))){				 
				 concurrentMap.remove(key);
				 return  true;
			 }
		}
		return  false;
	}
	public static void main(String[] args) {
		
		 Calendar calendar=Calendar.getInstance();
		 calendar.add(Calendar.SECOND, 1);
		
		DelaySnedMsg delaySnedMsg=new DelaySnedMsg(calendar.getTime().getTime());
		ReSendService.getIntanceo().submit(delaySnedMsg);
		
		 calendar.add(Calendar.SECOND, 1);
		ReSendService.getIntanceo().submit(new DelaySnedMsg(calendar.getTime().getTime()));
		 calendar.add(Calendar.SECOND, 1);
		ReSendService.getIntanceo().submit(new DelaySnedMsg(calendar.getTime().getTime()));
		
	}
}
